package com.sds.sweng.swat.miplatform.ui.design.models;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

@JsonAutoDetect
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
public abstract class MiplatformComponent implements IPropertySource {

	protected static IPropertyDescriptor[] descriptors;

	protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);

	public static final String
		CHILDREN = "children",
		NAME = "name";

	static {
		descriptors = new IPropertyDescriptor[] {
				new TextPropertyDescriptor(NAME, "Name")
		};
	}

	protected String name;

	protected String id = StringUtils.EMPTY;
	protected String text = StringUtils.EMPTY;
	protected String value = StringUtils.EMPTY;
	protected String style = StringUtils.EMPTY;
	protected String imageId = StringUtils.EMPTY;

	protected int left;
	protected int top;
	protected int width;
	protected int height;

	public MiplatformComponent() {
		setName(getClass().getSimpleName());
	}

	@JsonAnySetter
	public void setSubtypeHandler(String key, Object value) {
		//System.out.println(key + " is not binded.");
		listeners = new PropertyChangeSupport(this);
	}

	public int getDummyForPropertyChage() {
		return 0;
	}

	public MiplatformComponent clone() {
		try {
			MiplatformComponent cloneComponent = getClass().newInstance();
			cloneComponent.setId(getId());
			cloneComponent.setText(getText());
			cloneComponent.setValue(getValue());
			cloneComponent.setLeft(getLeft());
			cloneComponent.setTop(getTop());
			cloneComponent.setWidth(getWidth());
			cloneComponent.setHeight(getHeight());

			return cloneComponent;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public void setName(String name) {
		this.name = name;
		firePropertyChange(NAME, null, name);
	}

	public String getName() {
		return name;
	}

	public void addPropertyChangeListener(PropertyChangeListener listener) {
		listeners.addPropertyChangeListener(listener);
	}

	public void removePropertyChangeListener(PropertyChangeListener listener) {
		listeners.removePropertyChangeListener(listener);
	}

	protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
		listeners.firePropertyChange(propertyName, oldValue, newValue);
	}

	protected void fireStructureChange(String propertyName, Object child){
		listeners.firePropertyChange(propertyName, null, child);
	}

	@JsonIgnore
	public Object getEditableValue() {
		return this;
	}

	@JsonIgnore
	public IPropertyDescriptor[] getPropertyDescriptors() {
		return descriptors;
	}

	@JsonIgnore
	public Object getPropertyValue(Object id) {
		if (NAME.equals(id))
			return getName();

		return null;
	}

	@JsonIgnore
	public void setPropertyValue(Object id, Object value) {
		if (NAME.equals(id))
			setName((String) value);
	}

	@JsonIgnore
	public boolean isPropertySet(Object id) {
		return true;
	}

	public void resetPropertyValue(Object id) {
		// do nothing
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public int getLeft() {
		return left;
	}

	public void setLeft(int left) {
		this.left = left;
	}

	public int getTop() {
		return top;
	}

	public void setTop(int top) {
		this.top = top;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public String getStyle() {
		return style;
	}

	public void setStyle(String style) {
		this.style = style;
	}

	public String getImageId() {
		return imageId;
	}

	public void setImageId(String imageId) {
		this.imageId = imageId;
	}

}
